<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="1集合类概述1.1 集合类概念 什么是集合类? 12&gt;是一系列Jdk实现&#x2F;提供的Java类; 这些类用来让我们在Java代码逻辑中存储数据, 作为数据容器存在.&gt;Java集合类的本质: 就是一个Java工具类, 能用来让我们存储数据.  Java为什么要有集合类? 1&gt;很多情况下，我们需要对 &quot;一组对象&#x2F;某些数据&quot; 进行操作。而且很可能事先并不知道到底有多少个">
<meta property="og:type" content="article">
<meta property="og:title" content="Blog">
<meta property="og:url" content="https://guanhuaizhi0708.gitee.io/myblog/2023/05/24/01_%E9%9B%86%E5%90%88%E7%B1%BB/index.html">
<meta property="og:site_name" content="Blog">
<meta property="og:description" content="1集合类概述1.1 集合类概念 什么是集合类? 12&gt;是一系列Jdk实现&#x2F;提供的Java类; 这些类用来让我们在Java代码逻辑中存储数据, 作为数据容器存在.&gt;Java集合类的本质: 就是一个Java工具类, 能用来让我们存储数据.  Java为什么要有集合类? 1&gt;很多情况下，我们需要对 &quot;一组对象&#x2F;某些数据&quot; 进行操作。而且很可能事先并不知道到底有多少个">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-05-24T14:24:57.283Z">
<meta property="article:modified_time" content="2023-05-21T14:34:47.323Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/myblog/atom.xml" title="Blog" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/myblog/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/myblog/css/style.css">

  
    
<link rel="stylesheet" href="/myblog/fancybox/jquery.fancybox.min.css">

  
  
<meta name="generator" content="Hexo 6.3.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/myblog/" id="logo">Blog</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"><span class="fa fa-bars"></span></a>
        
          <a class="main-nav-link" href="/myblog/">Home</a>
        
          <a class="main-nav-link" href="/myblog/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
        
          <a class="nav-icon" href="/myblog/atom.xml" title="RSS 订阅"><span class="fa fa-rss"></span></a>
        
        <a class="nav-icon nav-search-btn" title="搜索"><span class="fa fa-search"></span></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="搜索"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://guanhuaizhi0708.gitee.io/myblog"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-01_集合类" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/myblog/2023/05/24/01_%E9%9B%86%E5%90%88%E7%B1%BB/" class="article-date">
  <time class="dt-published" datetime="2023-05-24T14:24:57.283Z" itemprop="datePublished">2023-05-24</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h1 id="1集合类概述"><a href="#1集合类概述" class="headerlink" title="1集合类概述"></a>1集合类概述</h1><h2 id="1-1-集合类概念"><a href="#1-1-集合类概念" class="headerlink" title="1.1 集合类概念"></a>1.1 集合类概念</h2><blockquote>
<p>什么是集合类?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt;是一系列Jdk实现/提供的Java类; 这些类用来让我们在Java代码逻辑中存储数据, 作为数据容器存在.</span><br><span class="line">&gt;Java集合类的本质: 就是一个Java工具类, 能用来让我们存储数据.</span><br></pre></td></tr></table></figure>

<p>Java为什么要有集合类?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;很多情况下，我们需要对 <span class="string">&quot;一组对象/某些数据&quot;</span> 进行操作。而且很可能事先并不知道到底有多少个对象。为了解决这个问题呢，所以,Java 就创建了一些特殊的JAVA类型用来存储数据, 这些被创建的类型也就是所谓的集合类.(为了解决: 存储更多类型问题, 扩容问题,  数据查找问题, 数据删除问题等等)</span><br></pre></td></tr></table></figure>
</blockquote>
<blockquote>
<p>Java的集合类有哪些?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;Java中的集合类, 分为两大类:</span><br><span class="line">   <span class="comment">//  Collection集合体系: 存储单个数据</span></span><br><span class="line">   <span class="comment">//  Map集合体系: 存储键值对(key-value)数据</span></span><br><span class="line"></span><br><span class="line">&gt;注意: key-value具有数据的自我描述性. (数据本身能描述自己)</span><br></pre></td></tr></table></figure>
</blockquote>
<blockquote>
<p>对于一个集合类我们要注意哪些相关的问题</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, 这个集合类的父子关系</span></span><br><span class="line">&gt;<span class="comment">// 2, 表现什么数据结构</span></span><br><span class="line">&gt;<span class="comment">// 3, 底层结构是什么</span></span><br><span class="line">&gt;<span class="comment">// 4, (如果是数组) 扩容机制和初始长度</span></span><br><span class="line">&gt;<span class="comment">// 5, 有序, 重复, null</span></span><br><span class="line">&gt;<span class="comment">// 6, 是否线程安全</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="1-2-手写集合类"><a href="#1-2-手写集合类" class="headerlink" title="1.2, 手写集合类"></a>1.2, 手写集合类</h2><blockquote>
<p>数组实现数据容器&#x2F;集合类</p>
<p>单向链表实现数据容器&#x2F;集合类</p>
<p>双向链表实现数据容器&#x2F;集合类</p>
</blockquote>
<h2 id="1-3-泛型"><a href="#1-3-泛型" class="headerlink" title="1.3, 泛型"></a>1.3, 泛型</h2><h3 id="1-3-1-概述"><a href="#1-3-1-概述" class="headerlink" title="1.3.1 概述"></a>1.3.1 概述</h3><blockquote>
<p>泛型</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 所谓泛型, 就是参数化类型, 当我们在写代码时候, 如果最开始不确定某个代码在逻辑设计的时候, 是什么类型;  我们可以选择假定一种类型来代指, 当我们真正使用的时候在指明具体的类型.</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// Java中的泛型是在JDK1.5时候出现.   </span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&gt;泛型的好处</span><br><span class="line">&gt;a. 提高了程序的安全性</span><br><span class="line">&gt;b. 将运行期遇到的问题转移到了编译期</span><br><span class="line">&gt;c. 省去了类型强转的麻烦(省去了我们来做类型强转, 实际底层jvm做了类型强转)</span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="1-3-2-泛型的使用"><a href="#1-3-2-泛型的使用" class="headerlink" title="1.3.2 泛型的使用"></a>1.3.2 泛型的使用</h3><h4 id="1-3-2-1-泛型类-必须知道"><a href="#1-3-2-1-泛型类-必须知道" class="headerlink" title="1.3.2.1 泛型类: 必须知道"></a>1.3.2.1 泛型类: 必须知道</h4><blockquote>
<p>泛型类: </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 所谓泛型类, 就是把泛型定义在类上.</span></span><br><span class="line">&gt;<span class="comment">// 在类型之后使用&lt;&gt;定义泛型</span></span><br><span class="line">&gt;格式:  class 类名  &lt;泛型类型<span class="number">1</span>,…&gt;</span><br></pre></td></tr></table></figure>

<p>注意1: 使用的写法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1,标准写法 jdk1.5标准写法:  在前后的&lt;&gt;都指明泛型类型</span></span><br><span class="line">&gt;User&lt;Integer&gt; zs = <span class="keyword">new</span> <span class="title class_">User</span>&lt;Integer&gt;(<span class="string">&quot;zs&quot;</span>, <span class="number">18</span>);</span><br><span class="line">&gt;<span class="type">Integer</span> <span class="variable">age</span> <span class="operator">=</span> zs.age;</span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 2, 简化写法  jdk1.7时候简化的写法:  可以省略后面的&lt;&gt;泛型 </span></span><br><span class="line">&gt;User&lt;Integer&gt; zs1 = <span class="keyword">new</span> <span class="title class_">User</span>&lt;&gt;(<span class="string">&quot;zs&quot;</span>, <span class="number">18</span>);</span><br><span class="line">&gt;<span class="type">Integer</span> <span class="variable">age1</span> <span class="operator">=</span> zs1.age;</span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 3, 如果某个地方需要我们在使用的时候指明泛型, 但是我们没有指明, 那么这个需要被指明的泛型类型默认为Object</span></span><br><span class="line">&gt;<span class="comment">//   建议(只是建议): 如果某个地方设计了泛型, 建议指明</span></span><br><span class="line">&gt;<span class="type">User</span> <span class="variable">zs2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>(<span class="string">&quot;zs&quot;</span>, <span class="number">18</span>);</span><br><span class="line">&gt;<span class="type">Object</span> <span class="variable">age2</span> <span class="operator">=</span> zs2.age;</span><br></pre></td></tr></table></figure>

<p>注意2:  多泛型问题</p>
<p>​         虽然从语法上讲, 我们可以在一个泛型类上假设很多泛型类型(语法完全允许); 但是不建议(强烈)超过2个</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 我们定义了一个对泛型的泛型类, 那么在使用的时候, 如果要指明泛型类型, 必须都/全部指明</span></span><br><span class="line">&gt;User22&lt;String, Integer, Integer&gt; user = <span class="keyword">new</span> <span class="title class_">User22</span>&lt;&gt;();</span><br><span class="line">&gt;user.name = <span class="string">&quot;zs&quot;</span>;</span><br><span class="line">&gt;user.age = <span class="number">18</span>;</span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 我们可以在一个泛型类上定义多个泛型, 以逗号分隔</span></span><br><span class="line">&gt;<span class="comment">// 我们在泛型类上, 定义了某个泛型, 但是没有使用也是允许的</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">User22</span> &lt;XXXX, YYY, ZZZ&gt; &#123;</span><br><span class="line">&gt;XXXX name;</span><br><span class="line">&gt;YYY age;</span><br><span class="line">&gt;&#125;</span><br></pre></td></tr></table></figure>

<p>注意3: 泛型的假设写法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 定义泛型的一般写法</span></span><br><span class="line">&gt;<span class="comment">// T :  Type</span></span><br><span class="line">&gt;<span class="comment">// E :  Element</span></span><br><span class="line">&gt;<span class="comment">// K :  Key</span></span><br><span class="line">&gt;<span class="comment">// V :  Value</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">User23</span> &lt;T&gt; &#123;</span><br><span class="line">&gt;String name;</span><br><span class="line">&gt;T age;</span><br><span class="line">&gt;&#125;</span><br></pre></td></tr></table></figure>

<p>注意4:  泛型必须是引用类型 (实际上是不影响使用的, 拆箱装箱)</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 报错, 泛型不允许使用基本类型</span></span><br><span class="line">&gt;<span class="comment">// User23&lt;int&gt; user231 = new User23&lt;int&gt;();</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> <span class="number">10</span>;</span><br><span class="line">&gt;User23&lt;Integer&gt; user23 = <span class="keyword">new</span> <span class="title class_">User23</span>&lt;Integer&gt;();</span><br><span class="line">&gt;user23.age = <span class="number">18</span>;</span><br><span class="line">&gt;user23.age = num;</span><br></pre></td></tr></table></figure>

<p>注意5: 泛型不允许new</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">User24</span>  &lt;T&gt;&#123;</span><br><span class="line">&gt;String name;</span><br><span class="line">&gt;T age;</span><br><span class="line"></span><br><span class="line">&gt;<span class="keyword">public</span> <span class="title function_">User24</span><span class="params">()</span>&#123;</span><br><span class="line">  <span class="built_in">this</span>.name = <span class="string">&quot;zs&quot;</span>;</span><br><span class="line">  <span class="comment">// this.age = new T(); // 报错</span></span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;&#125;</span><br></pre></td></tr></table></figure>

<p>注意6: 泛型类定义的泛型的作用域</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 泛型类上定义一个泛型, 它的作用域仅仅局限于自己的类名和类体内</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">F</span>&#123;</span><br><span class="line">&gt;<span class="comment">// T ft; 报错</span></span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">M</span>  &lt;T&gt; <span class="keyword">extends</span> <span class="title class_">F</span>&#123;</span><br><span class="line">&gt;T t;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S</span> <span class="keyword">extends</span> <span class="title class_">M</span>&#123;</span><br><span class="line">&gt;<span class="comment">// T st; 报错</span></span><br><span class="line">&gt;&#125;</span><br></pre></td></tr></table></figure>

<p>注意7: 泛型的父子继承关系</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">F</span> &lt;T&gt;&#123;</span><br><span class="line">&gt;T ft;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S1</span> <span class="keyword">extends</span> <span class="title class_">F</span>&#123;&#125; <span class="comment">// S1 有个Object类型的ft</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S2</span> <span class="keyword">extends</span> <span class="title class_">F</span>&lt;Integer&gt;&#123;&#125;<span class="comment">// S2 有个Integer类型的ft</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S3</span> <span class="keyword">extends</span> <span class="title class_">F</span>&lt;String&gt;&#123;&#125; <span class="comment">// S3 有个String类型的ft</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S4</span>&lt;E&gt; <span class="keyword">extends</span> <span class="title class_">F</span>&lt;String&gt;&#123;&#125; <span class="comment">// S4 有个String类型的ft</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S5</span>&lt;E&gt; <span class="keyword">extends</span> <span class="title class_">F</span>&lt;E&gt;&#123;&#125;<span class="comment">// S5里面的ft参照于泛型类型E</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S6</span>&lt;T&gt; <span class="keyword">extends</span> <span class="title class_">F</span>&lt;String&gt;&#123;&#125;<span class="comment">// S6有个String类型的ft</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S7</span>&lt;T&gt; <span class="keyword">extends</span> <span class="title class_">F</span>&lt;T&gt;&#123;&#125; <span class="comment">// 等价于S5的写法</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h4 id="1-3-2-2-泛型接口"><a href="#1-3-2-2-泛型接口" class="headerlink" title="1.3.2.2 泛型接口"></a>1.3.2.2 泛型接口</h4><blockquote>
<p>泛型接口: 就是把泛型定义在接口上</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="keyword">interface</span> <span class="title class_">F</span>&lt;T&gt;&#123;</span><br><span class="line">&gt;<span class="keyword">public</span> T  <span class="title function_">getFt</span><span class="params">(T t)</span>;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S1</span> <span class="keyword">implements</span> <span class="title class_">F</span>&#123;</span><br><span class="line">&gt;<span class="meta">@Override</span></span><br><span class="line">&gt;<span class="keyword">public</span> Object <span class="title function_">getFt</span><span class="params">(Object o)</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S2</span> <span class="keyword">implements</span> <span class="title class_">F</span>&lt;String&gt;&#123;</span><br><span class="line">&gt;<span class="meta">@Override</span></span><br><span class="line">&gt;<span class="keyword">public</span> String <span class="title function_">getFt</span><span class="params">(String s)</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S3</span>&lt;E&gt; <span class="keyword">implements</span> <span class="title class_">F</span>&lt;Integer&gt;&#123;</span><br><span class="line">&gt;<span class="meta">@Override</span></span><br><span class="line">&gt;<span class="keyword">public</span> Integer <span class="title function_">getFt</span><span class="params">(Integer integer)</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S4</span>&lt;E&gt; <span class="keyword">implements</span> <span class="title class_">F</span>&lt;E&gt;&#123;</span><br><span class="line">&gt;<span class="meta">@Override</span></span><br><span class="line">&gt;<span class="keyword">public</span> E <span class="title function_">getFt</span><span class="params">(E e)</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S5</span>&lt;T&gt; <span class="keyword">implements</span> <span class="title class_">F</span>&lt;T&gt;&#123;</span><br><span class="line">&gt;<span class="meta">@Override</span></span><br><span class="line">&gt;<span class="keyword">public</span> T <span class="title function_">getFt</span><span class="params">(T t)</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;&#125;</span><br></pre></td></tr></table></figure>
</blockquote>
<h4 id="1-3-2-3-泛型方法-了解"><a href="#1-3-2-3-泛型方法-了解" class="headerlink" title="1.3.2.3 泛型方法: 了解"></a>1.3.2.3 泛型方法: 了解</h4><blockquote>
<p>泛型方法: 就是把泛型定义在方法上 </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="type">F</span> <span class="variable">f</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">F</span>();</span><br><span class="line">&gt;<span class="comment">// 对于一个泛型方法, </span></span><br><span class="line">&gt;<span class="comment">// 不需要手动指明泛型, 它会自动的根据方法的调用参数推断出泛型的类型</span></span><br><span class="line">&gt;<span class="type">String</span> <span class="variable">zs</span> <span class="operator">=</span> f.getT(<span class="string">&quot;zs&quot;</span>);</span><br><span class="line">&gt;<span class="type">Integer</span> <span class="variable">t</span> <span class="operator">=</span> f.getT(<span class="number">18</span>);</span><br><span class="line"></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">F</span>&#123;</span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 这是一个泛型方法: 因为泛型定义在方法上, 要放在返回值之前</span></span><br><span class="line">&gt;<span class="keyword">public</span> &lt;T&gt; T <span class="title function_">getT</span><span class="params">(T t)</span>&#123;</span><br><span class="line">  <span class="keyword">return</span> t;	</span><br><span class="line">&gt;&#125;</span><br><span class="line">&gt;&#125;</span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="1-3-3-泛型的通配-了解"><a href="#1-3-3-泛型的通配-了解" class="headerlink" title="1.3.3 泛型的通配: 了解"></a>1.3.3 泛型的通配: 了解</h3><blockquote>
<p>首先泛型不允许类似数组一样协变: 害怕带来数组协变存储数据的类型不匹配问题</p>
<p>又想拥有类似数组协变的功效</p>
</blockquote>
<blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">//        ① 泛型通配符&lt;?&gt;</span></span><br><span class="line">&gt;<span class="comment">//                  用来代指任意类型</span></span><br><span class="line">&gt;<span class="comment">//        ② &lt;? extends E&gt;</span></span><br><span class="line">&gt;<span class="comment">//                向下限定，代指E类型 以及 E的子类型</span></span><br><span class="line">&gt;<span class="comment">//        ③ &lt;? super E&gt;</span></span><br><span class="line">&gt;<span class="comment">//                向上限定，代指E类型  以及  E的父类型</span></span><br><span class="line"></span><br><span class="line">&gt;MyLinkedCollection&lt;?&gt; collection1 = <span class="keyword">new</span> <span class="title class_">MyLinkedCollection</span>&lt;String&gt;();</span><br><span class="line">&gt;MyLinkedCollection&lt;? <span class="keyword">extends</span> <span class="title class_">F</span>&gt; collection2 = <span class="keyword">new</span> <span class="title class_">MyLinkedCollection</span>&lt;F&gt;();</span><br><span class="line">&gt;MyLinkedCollection&lt;? <span class="built_in">super</span> F&gt; collection3 = <span class="keyword">new</span> <span class="title class_">MyLinkedCollection</span>&lt;Object&gt;();</span><br><span class="line"></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">F</span>&#123;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S1</span> <span class="keyword">extends</span> <span class="title class_">F</span>&#123;&#125;</span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">S2</span> <span class="keyword">extends</span> <span class="title class_">F</span>&#123;&#125;</span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="1-3-4泛型擦除"><a href="#1-3-4泛型擦除" class="headerlink" title="1.3.4泛型擦除"></a>1.3.4泛型擦除</h3><blockquote>
<p>什么泛型擦除: Java的泛型只存在于编译之前, 当编译的时候, 泛型会被擦除成Object</p>
</blockquote>
<h1 id="2-Collection"><a href="#2-Collection" class="headerlink" title="2, Collection"></a>2, Collection</h1><h2 id="2-1-Collection的特点"><a href="#2-1-Collection的特点" class="headerlink" title="2.1 Collection的特点"></a>2.1 Collection的特点</h2><blockquote>
<p>Collection的特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Collection是Collection集合体系的顶级接口</span></span><br><span class="line">&gt;<span class="comment">// 2, Collection定义了一个数据容器(用来存储数据的)</span></span><br><span class="line">&gt;<span class="comment">// 3, Collection的一些子实现存储数据有序, Collection一些子实现存储数据无序</span></span><br><span class="line">&gt;<span class="comment">// 4, Collection的一些子实现允许存储重复数据, Collection一些子实现不允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 5, Collection的一些子实现允许存储null, Collection一些子实现不允许存储null</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="2-2-Collection的api"><a href="#2-2-Collection的api" class="headerlink" title="2.2 Collection的api"></a>2.2 Collection的api</h2><blockquote>
<p>Collection定义的哪些API</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// -----------Collection: 增删改查相关的api (作为数据容器具有)-------------</span></span><br><span class="line">&gt;<span class="comment">//        boolean add(E e): 添加方法</span></span><br><span class="line">&gt;<span class="comment">//        boolean addAll(Collection&lt;? extends E&gt; c): 添加所有</span></span><br><span class="line">&gt;<span class="comment">//        boolean remove(Object o): 根据内容删除</span></span><br><span class="line">&gt;<span class="comment">//        boolean removeAll(Collection&lt;?&gt; c): 删除所有匹配数据</span></span><br><span class="line">&gt;<span class="comment">//        boolean contains(Object o): 查找</span></span><br><span class="line">&gt;<span class="comment">//        boolean containsAll(Collection&lt;?&gt; c): 查找是否都存在</span></span><br><span class="line">&gt;<span class="comment">//        boolean retainAll(Collection&lt;?&gt; c): 保留匹配数据</span></span><br><span class="line">&gt;<span class="comment">// -----------辅助方法: size isEmpty, equals, hashCode..--------------</span></span><br><span class="line">&gt;<span class="comment">//        int size()</span></span><br><span class="line">&gt;<span class="comment">//        boolean isEmpty()</span></span><br><span class="line">&gt;<span class="comment">//        boolean equals(Object o): 重写了这个方法, 按照内容进行比较</span></span><br><span class="line">&gt;<span class="comment">//        int hashCode()</span></span><br><span class="line">&gt;<span class="comment">//        void clear()</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// -----------特殊方法: 帮助我们对Collection进行遍历的---------------------------</span></span><br><span class="line">&gt;<span class="comment">//        Object[] toArray()</span></span><br><span class="line">&gt;<span class="comment">//        返回包含此 collection 中所有元素的数组。</span></span><br><span class="line">&gt;<span class="comment">//        &lt;T&gt; T[] toArray(T[] a)</span></span><br><span class="line"><span class="comment">//        返回包含此 collection 中所有元素的数组；返回与指定数组的运行时类型相同。</span></span><br><span class="line">&gt;<span class="comment">//        Iterator&lt;E&gt; iterator()</span></span><br><span class="line">&gt;<span class="comment">//        返回在此 collection 的元素上进行迭代的迭代器。</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="toArray-方法"><a href="#toArray-方法" class="headerlink" title="toArray()方法"></a>toArray()方法</h3><blockquote>
<p>我们很多时候, 需要对集合类(数据容器 )进行数据遍历, 但是Collection没有办法直接遍历, 所以Collection定义了一个toArray方法, 把里面存储的数据放到数组中返回, 就可以实现数据遍历</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&gt;第一个toArray()方法</span><br><span class="line">&gt;<span class="comment">//        Object[] toArray()</span></span><br><span class="line">&gt;<span class="comment">//        返回包含此 collection 中所有元素的数组。 ( 为什么返回Object[]类型的数组, 是因为没有办法在toArray中根据泛型类型直接创建数组, 所以只能用Object类型的数组来存储数据 )</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&gt;第二个toArray()方法 : 泛型方法</span><br><span class="line">&gt;<span class="comment">//        &lt;T&gt; T[]  toArray(T[] a)</span></span><br><span class="line">&gt;<span class="comment">//        返回包含此 collection 中所有元素的数组；返回数组的运行时类型与指定数组的运行时类型相同。</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// ps1: 虽然这是个泛型方法(从泛型语法角度上传任何类型的数组都是可以的), 但是在实际运行的时候, 只有这个数组类型传对(和存储数据类型匹配), 才能正常运行  </span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// ps2: 在使用这个泛型方法的时候, 如果数组足够长(假设 collection存储元素数量为n, 数组长度至少是n), 返回的数据和传进去的参数, 实际上是一个数组 ;   如果我们给定参数数组长度不够长(空间不够容纳所有的collection元素),那么传进去的数组仅作为类型标记, 和返回的数组并不是同一个数组</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// ps3: 在使用这个泛型方法的时候, 如果数组过长(collection存储元素数量为n, 数组长度大于n), 它会它数组的第n+1个位置置为null, n+1之后的位置不再处理</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="iterator"><a href="#iterator" class="headerlink" title="iterator"></a>iterator</h3><blockquote>
<p>在设计Collection代码的时候, toArray()方法虽然能实现对数据的遍历, 但是toArray()需要创建数组复制源Collection数据(从内存和时间效率上讲)效率比较低. </p>
<p>所以Collection提供了一种”原地”遍历的方式: iterator()方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 代码示例</span></span><br><span class="line">   Collection&lt;String&gt; collection = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">   collection.add(<span class="string">&quot;zs&quot;</span>);</span><br><span class="line">   collection.add(<span class="string">&quot;ls&quot;</span>);</span><br><span class="line">   collection.add(<span class="string">&quot;wu&quot;</span>);</span><br><span class="line">   collection.add(<span class="string">&quot;zl&quot;</span>);</span><br><span class="line"></span><br><span class="line">   Iterator&lt;String&gt; iterator = collection.iterator();</span><br><span class="line"></span><br><span class="line">   <span class="keyword">while</span> (iterator.hasNext())&#123;</span><br><span class="line">       System.out.println(iterator.next());</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>

<p>1,  iterator本质</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">//  Collection提供了一个toArray方法, 把数据转存到数组中, 然后遍历, 但是效率不高,所以设计了iterator(原地遍历: 不复制数据, 仅维护标记)</span></span><br><span class="line">&gt;<span class="comment">// 通过Collection的iterator方法产生了一个iterator对象, 这个对象的在内存上的本质就是iterator对象内维护了一些指向源collection对象数据的标记;   </span></span><br></pre></td></tr></table></figure>

<p>2, iterator方法返回一个Iterator类型的对象, 这个Iterator类型的对象有三个方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// Iterator类型方法:</span></span><br><span class="line">&gt;<span class="type">boolean</span> <span class="title function_">hasNext</span><span class="params">()</span>: 向后是否可以遍历       </span><br><span class="line">&gt;E <span class="title function_">next</span><span class="params">()</span> : 向后遍历</span><br><span class="line">&gt;<span class="keyword">void</span> <span class="title function_">remove</span><span class="params">()</span> : 删除刚刚遍历过的元素: (不要在未遍历之前删除, 也不要做连续的删除)()</span><br></pre></td></tr></table></figure>

<p>3, 遍历&#x2F;删除数据, 操作的是什么数据? </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// iterator对象内是维护的指向源collection对象数据的标记;  那么我们通过iterator对象来做遍历(遍历或者删除), 实际上是直接遍历(遍历或者删除)原collection对象中的数据</span></span><br><span class="line"></span><br><span class="line">&gt;所以对于iterator的删除操作:</span><br><span class="line">&gt;<span class="comment">// 在使用iterator的remove方法时, 不能在未遍历之前删除, 也不能做连续的删除</span></span><br><span class="line">&gt;<span class="comment">// remove不能在未遍历之前删除, 不能连续的删除:  也就意味着删除使用范围很狭窄(只有一个使用场景: 在遍历的过程, 我们觉得某个遍历数据, 不符合预期,把它删除), iterator主要是用来做遍历的(关注:hasNext, next )</span></span><br></pre></td></tr></table></figure>

</blockquote>
<h4 id="并发修改异常问题"><a href="#并发修改异常问题" class="headerlink" title="并发修改异常问题"></a>并发修改异常问题</h4><blockquote>
<p>并发修改异常来源</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 一些Collection的子实现是线程不安全的(加锁会导致运行效率降低), 在使用Iterator遍历的时候, 就会产生线程安全问题, 但是又不希望通过锁来保证线程安全(加锁会导致运行效率降低) ; </span></span><br><span class="line">&gt;<span class="comment">// 所以一些集合类就维护了一个标记(标记修改次数的标记), 当源集合数据发生修改, 标记会增加;</span></span><br><span class="line">&gt;<span class="comment">// 在iterator对象中为了保证在遍历过程中源集合类数据没有被修改, 会在每次遍历之前检测自己保存的修改次数记录和源集合类是否一样, 如果不一样, 就认为源集合数据被别的线程修改, 抛出并发修改异常. </span></span><br><span class="line">&gt;<span class="comment">// 这是为了多线程遍历数据设计</span></span><br><span class="line">&gt;<span class="comment">// 但是可能导致单线程情况下, 在遍历的过程中如果直接使用源集合类的修改结构的方法, 直接修改源集合数据, 也会抛出并发修改异常 </span></span><br></pre></td></tr></table></figure>

<p>怎么避免在单线程情况下产生并发修改异常: </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 在遍历之前直接修改源集合数据, 或者在遍历完成之后修改, 不要在遍历中间过程修改</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="foreach"><a href="#foreach" class="headerlink" title="foreach"></a>foreach</h3><blockquote>
<p>在使用foreach循环遍历Java集合类的时候, 它的底层就是iterator迭代</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&gt;注意一: </span><br><span class="line">&gt;<span class="comment">// 我们Java中 foreach/增强for/加强for循环,  是依赖于iterator迭代 </span></span><br><span class="line">&gt;<span class="comment">// 也就意味着, 要使用增强的for循环遍历数据, 就要有iterator方法</span></span><br><span class="line">&gt;<span class="comment">// 同时也意味着, 如果我们使用foreach循环遍历某个Java容器, 不应该在遍历的过程中, 调用源集合类修改结构的方法直接修改源集合数据(会爆出并发修改异常)</span></span><br><span class="line"></span><br><span class="line">&gt;注意二:</span><br><span class="line">&gt;<span class="comment">// 如果我们要使用foreach遍历我们自己设计的数据容器, 应该让我们自己设计的数据容器父子关系上满足是Iterable的子类; 因为Iterable中定义了iterator方法</span></span><br><span class="line"></span><br><span class="line">&gt;注意三:了解 (后续才讲)</span><br><span class="line">&gt;<span class="comment">// 我们知道foreach循环在Java中底层是iterator,  数组也是这样吗?</span></span><br><span class="line">&gt;数组的foreach底层实际上还是fori循环</span><br><span class="line"></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="3-List"><a href="#3-List" class="headerlink" title="3, List"></a>3, List</h1><h2 id="3-1-List的特点"><a href="#3-1-List的特点" class="headerlink" title="3.1 List的特点"></a>3.1 List的特点</h2><blockquote>
<p>List的特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, List是Collection的接口的子接口</span></span><br><span class="line">&gt;<span class="comment">// 2, List在Collection作为数据容器定义的基础上, 定义了数据结构为线性表</span></span><br><span class="line">&gt;<span class="comment">// 3, List所有子实现存储数据都有序</span></span><br><span class="line">&gt;<span class="comment">// 4, List允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 5, List允许存储null</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="3-2-List的api"><a href="#3-2-List的api" class="headerlink" title="3.2 List的api"></a>3.2 List的api</h2><blockquote>
<p>List的api基本上是在Collection的基础上增加了下标操作的api		</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// -----首选拥有从Collection继承来的api: 略(可以参考Collection的api看一下)---------</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// -----添加删除相关的: List下标相关操作(看一下)---------------------</span></span><br><span class="line">&gt;<span class="comment">//        void add(int index, E element): 根据下标的添加</span></span><br><span class="line">&gt;<span class="comment">//        boolean addAll(int index, Collection&lt;? extends E&gt; c): 根据下标添加所有</span></span><br><span class="line">&gt;<span class="comment">//        E remove(int index): 根据下标的删除</span></span><br><span class="line">&gt;<span class="comment">//        E get(int index): 根据下标获取下标位置存储的内容</span></span><br><span class="line">&gt;<span class="comment">//        int indexOf(Object o): 根据内容查找这个数据出现的第一次下标位置</span></span><br><span class="line">&gt;<span class="comment">//        int lastIndexOf(Object o): 根据内容查找这个数据出现的最后一次下标位置</span></span><br><span class="line">&gt;<span class="comment">//        E set(int index, E element): 根据修改下标位置存储的内容</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// ------特殊api: List下标相关操作--------------------------</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        ListIterator&lt;E&gt; listIterator()</span></span><br><span class="line">&gt;<span class="comment">//        ListIterator&lt;E&gt; listIterator(int index): </span></span><br><span class="line">&gt;<span class="comment">// 		  提供了一个从某个位置开始, 不仅可以向后遍历, 也可以向前遍历的方式previous()</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        List&lt;E&gt; subList(int fromIndex, int toIndex)</span></span><br><span class="line">&gt;<span class="comment">//        返回列表中指定的 fromIndex（包括 ）和 toIndex（不包括）之间的部分视图。</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="subList"><a href="#subList" class="headerlink" title="subList"></a>subList</h3><blockquote>
<p>是一个视图方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt;什么是视图方法:</span><br><span class="line">&gt;<span class="comment">// 在某些数据的基础上, 我们可以通过视图方法, 看上去从源数据&quot;提取&quot;出来某些符合我们要求的数据,  实际上我们并没有真的获得这些数据,  而是维护了一些指向这些数据的标记,  意味着视图方法所获得的数据还是和源数据是同一份数据, 这进一步意味着, 如果我们对视图方法获得的数据进行增删改查, 实际上还是对源数据的增删改查  </span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">     <span class="comment">// zs   ls  wu  zl        </span></span><br><span class="line">List&lt;String&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">     list.add(<span class="string">&quot;zs&quot;</span>);</span><br><span class="line">     list.add(<span class="string">&quot;ls&quot;</span>);</span><br><span class="line">     list.add(<span class="string">&quot;wu&quot;</span>);</span><br><span class="line">     list.add(<span class="string">&quot;zl&quot;</span>);</span><br><span class="line"></span><br><span class="line">     <span class="comment">// ls  wu</span></span><br><span class="line">     List&lt;String&gt; strings = list.subList(<span class="number">1</span>, <span class="number">3</span>);</span><br><span class="line"></span><br><span class="line">     <span class="comment">// wu</span></span><br><span class="line">     strings.remove(<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">     System.out.println(strings); <span class="comment">// wu</span></span><br><span class="line">     System.out.println(list);<span class="comment">// zs  wu  zl</span></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">//        List&lt;E&gt; subList(int fromIndex, int toIndex)</span></span><br><span class="line">&gt;<span class="comment">//        返回列表中指定的 fromIndex（包括 ）和 toIndex（不包括）之间的部分视图。</span></span><br><span class="line">&gt;注意: subList是一个视图方法:  所谓视图方法就是并没有真正获取/持有什么数据, 只是产生一个对象, 持有一些标记指向源数据(也就是看上去是subList从源数据切割出来一些数据, 但是实际上, 只是维护一些标记指向源数据)</span><br><span class="line"></span><br><span class="line">&gt;注意: 视图方法也会产生并发修改异常 (怎么避免: 在使用视图结果的过程中, 不要调用源集合类修改结构的方法修改源集合数据)</span><br></pre></td></tr></table></figure>

</blockquote>
<h1 id="4-ArrayList"><a href="#4-ArrayList" class="headerlink" title="4, ArrayList"></a>4, ArrayList</h1><h2 id="4-1-ArrayList的特点"><a href="#4-1-ArrayList的特点" class="headerlink" title="4.1 ArrayList的特点"></a>4.1 ArrayList的特点</h2><blockquote>
<p>ArrayList的特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, ArrayList是List接口的子实现</span></span><br><span class="line">&gt;<span class="comment">// 2, ArrayList数据结构是线性表</span></span><br><span class="line">&gt;<span class="comment">// 3, ArrayList底层是数组</span></span><br><span class="line">&gt;<span class="comment">// 4, ArrayList底层持有的数组默认初始长度10, 扩容机制1.5倍</span></span><br><span class="line">&gt;<span class="comment">// 5, ArrayList存储数据有序</span></span><br><span class="line">&gt;<span class="comment">// 6, ArrayList允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 7, ArrayList允许存储null</span></span><br><span class="line">&gt;<span class="comment">// 8, ArrayList线程不安全</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="4-2-ArrayList的构造方法"><a href="#4-2-ArrayList的构造方法" class="headerlink" title="4.2 ArrayList的构造方法"></a>4.2 ArrayList的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">//        ArrayList()</span></span><br><span class="line">&gt;<span class="comment">//        构造一个初始容量为 10 的空列表。</span></span><br><span class="line">&gt;<span class="comment">//        ArrayList(int initialCapacity)</span></span><br><span class="line">&gt;<span class="comment">//        构造一个具有指定初始容量的空列表。</span></span><br><span class="line">&gt;<span class="comment">//        ArrayList(Collection&lt;? extends E&gt; c)</span></span><br><span class="line">&gt;<span class="comment">//        构造一个包含指定 collection 的元素的列表，这些元素是按照该 collection 的迭代器返回它们的顺序排列的。</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="4-3-ArrayList的api"><a href="#4-3-ArrayList的api" class="headerlink" title="4.3 ArrayList的api"></a>4.3 ArrayList的api</h2><blockquote>
<p>api</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&gt;由于ArrayList作为List的直接子实现, 所以ArrayList实现的方法都基本上参照于List接口的定义.</span><br><span class="line">&gt;ArrayList并没有很多特殊的api. ArrayList的api基本都来源于List和Collection</span><br><span class="line">   </span><br><span class="line">&gt;(如果大家记忆:  记List和Collection即可)</span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// -------如下方法是ArrayList比较特殊的方法(作为了解即可, 不常用)--------------      </span></span><br><span class="line">&gt;<span class="comment">//        Object clone()</span></span><br><span class="line">&gt;<span class="comment">//        返回此 ArrayList 实例的浅表副本。删除原数据，不影响拷贝的容器的数据</span></span><br><span class="line">&gt;<span class="comment">//        void trimToSize()</span></span><br><span class="line">&gt;<span class="comment">//        将此 ArrayList 实例的容量调整为列表的当前大小。</span></span><br><span class="line">&gt;<span class="comment">//        void ensureCapacity(int minCapacity)</span></span><br><span class="line">&gt;<span class="comment">//        如有必要，增加此 ArrayList 实例的容量，以确保它至少能够容纳最小容量参数所指定的元素数。</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="5-Vector"><a href="#5-Vector" class="headerlink" title="5, Vector"></a>5, Vector</h1><h2 id="5-1-Vector的特点"><a href="#5-1-Vector的特点" class="headerlink" title="5.1 Vector的特点"></a>5.1 Vector的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Vector是List的子实现</span></span><br><span class="line">&gt;<span class="comment">// 2, Vector数据结构为线性表</span></span><br><span class="line">&gt;<span class="comment">// 3, Vector的底层结构是数组</span></span><br><span class="line">&gt;<span class="comment">// 4, Vector底层数组的默认长度10,  扩容机制(如果Vector有大于0的增量, 那么,每次扩容扩大增量个, 如果增量是小于等于0, 每次扩容扩为原来的2倍)</span></span><br><span class="line">&gt;<span class="comment">// 5, Vector存储数据有序</span></span><br><span class="line">&gt;<span class="comment">// 6, Vector允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 7, Vector允许存储null</span></span><br><span class="line">&gt;<span class="comment">// 8, 线程安全 (锁)</span></span><br><span class="line">&gt;<span class="comment">// 9, Vector是jdk1.0的时候出现 (ArrayList在jdk1.2时候出现, ArrayList出现就是为了取代Vector)</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="6-Stack"><a href="#6-Stack" class="headerlink" title="6, Stack"></a>6, Stack</h1><h2 id="6-1-Stack注意事项"><a href="#6-1-Stack注意事项" class="headerlink" title="6.1 Stack注意事项"></a>6.1 Stack注意事项</h2><blockquote>
<p>1, 在使用Stack的时候, 虽然我们可以使用来自于其父类继承add,remove…等方法, 但是建议不要使用.</p>
<p>2, Stack是一个栈, 但是是线程安全(效率略低), 所以Java提供了另个一个集合类, 也可以表示为栈, Queue接口下的Deque. (Deque接口主要是作为双端队列, 但是也定义了栈这种数据结构)</p>
</blockquote>
<h1 id="7-LinkedList"><a href="#7-LinkedList" class="headerlink" title="7, LinkedList"></a>7, LinkedList</h1><h2 id="7-1-LinkedList的特点"><a href="#7-1-LinkedList的特点" class="headerlink" title="7.1 LinkedList的特点"></a>7.1 LinkedList的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, LinkedList是List的子实现, 同时还是Deque接口的子实现.(主要把LinkedList看做List的子实现)</span></span><br><span class="line">&gt;<span class="comment">// 2, LinkedList数据结构表现为: 线性表, 队列, 双端队列, 栈</span></span><br><span class="line">&gt;<span class="comment">// 3, LinkedList底层是一个双向链表</span></span><br><span class="line">&gt;<span class="comment">// 4, LinkedList存储元素有序</span></span><br><span class="line">&gt;<span class="comment">// 5, LinkenList允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 6, LinkedList允许存储null</span></span><br><span class="line">&gt;<span class="comment">// 7, 线程不安全</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="7-2-LinkedList的构造方法"><a href="#7-2-LinkedList的构造方法" class="headerlink" title="7.2 LinkedList的构造方法"></a>7.2 LinkedList的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">//        LinkedList()</span></span><br><span class="line">&gt;<span class="comment">//        构造一个空列表。</span></span><br><span class="line">&gt;<span class="comment">//        LinkedList(Collection&lt;? extends E&gt; c)</span></span><br><span class="line">&gt;<span class="comment">//        构造一个包含指定 collection 中的元素的列表，这些元素按其 collection 的迭代器返回的顺序排列。</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="7-3-LinkedList的api"><a href="#7-3-LinkedList的api" class="headerlink" title="7.3 LinkedList的api"></a>7.3 LinkedList的api</h2><blockquote>
<p>api</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line">&gt;如果我们对LinkedList的api进行分类: 如下</span><br><span class="line">&gt;<span class="comment">// LinkedList具有Collection定义的方法</span></span><br><span class="line">&gt;<span class="comment">// LinkedList具有List定义的方法</span></span><br><span class="line">&gt;<span class="comment">// LinkedList具有Queue定义的方法(队列的api)</span></span><br><span class="line">&gt;<span class="comment">// LinkedList具有Deque定义的方法(双端队列,  栈)</span></span><br><span class="line">   </span><br><span class="line">&gt;<span class="comment">// -----------------------------------------------</span></span><br><span class="line">&gt;<span class="comment">// -----------Collection:  -------------</span></span><br><span class="line">&gt;<span class="comment">//        boolean add(E e): 添加方法</span></span><br><span class="line">&gt;<span class="comment">//        boolean addAll(Collection&lt;? extends E&gt; c): 添加所有</span></span><br><span class="line">&gt;<span class="comment">//        boolean remove(Object o): 根据内容删除</span></span><br><span class="line">&gt;<span class="comment">//        boolean removeAll(Collection&lt;?&gt; c): 删除所有匹配数据</span></span><br><span class="line">&gt;<span class="comment">//        boolean contains(Object o): 查找</span></span><br><span class="line">&gt;<span class="comment">//        boolean containsAll(Collection&lt;?&gt; c): 查找是否都存在</span></span><br><span class="line">&gt;<span class="comment">//        boolean retainAll(Collection&lt;?&gt; c): 保留匹配数据</span></span><br><span class="line">   </span><br><span class="line">&gt;<span class="comment">//        int size()</span></span><br><span class="line">&gt;<span class="comment">//        boolean isEmpty()</span></span><br><span class="line">&gt;<span class="comment">//        boolean equals(Object o): 重写了这个方法, 按照内容进行比较</span></span><br><span class="line">&gt;<span class="comment">//        int hashCode()</span></span><br><span class="line">&gt;<span class="comment">//        void clear()</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        Object[] toArray()</span></span><br><span class="line">&gt;<span class="comment">//        返回包含此 collection 中所有元素的数组。</span></span><br><span class="line">&gt;<span class="comment">//        &lt;T&gt; T[] toArray(T[] a)</span></span><br><span class="line">&gt;<span class="comment">//        返回包含此 collection 中所有元素的数组；返回与指定数组的运行时类型相同。</span></span><br><span class="line">&gt;<span class="comment">//        Iterator&lt;E&gt; iterator()</span></span><br><span class="line">&gt;<span class="comment">//        返回在此 collection 的元素上进行迭代的迭代器。 </span></span><br><span class="line">   </span><br><span class="line">   </span><br><span class="line">&gt;<span class="comment">// -----------List:  -------------</span></span><br><span class="line">&gt;<span class="comment">//        void add(int index, E element): 根据下标的添加</span></span><br><span class="line">&gt;<span class="comment">//        boolean addAll(int index, Collection&lt;? extends E&gt; c): 根据下标添加所有</span></span><br><span class="line">&gt;<span class="comment">//        E remove(int index): 根据下标的删除</span></span><br><span class="line">&gt;<span class="comment">//        E get(int index): 根据下标获取下标位置存储的内容</span></span><br><span class="line">&gt;<span class="comment">//        int indexOf(Object o): 根据内容查找这个数据出现的第一次下标位置</span></span><br><span class="line">&gt;<span class="comment">//        int lastIndexOf(Object o): 根据内容查找这个数据出现的最后一次下标位置</span></span><br><span class="line">&gt;<span class="comment">//        E set(int index, E element): 根据修改下标位置存储的内容</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        ListIterator&lt;E&gt; listIterator()</span></span><br><span class="line">&gt;<span class="comment">//        ListIterator&lt;E&gt; listIterator(int index): </span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        List&lt;E&gt; subList(int fromIndex, int toIndex)</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// -----------Queue:  -------------</span></span><br><span class="line">&gt;<span class="comment">//        boolean offer(E e)</span></span><br><span class="line">&gt;<span class="comment">//        将指定元素添加到此列表的末尾（最后一个元素）。</span></span><br><span class="line">&gt;<span class="comment">//        E peek()</span></span><br><span class="line">&gt;<span class="comment">//        获取但不移除此列表的头（第一个元素）。</span></span><br><span class="line">&gt;<span class="comment">//        E poll()</span></span><br><span class="line">&gt;<span class="comment">//        获取并移除此列表的头（第一个元素）</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// -----------Deque:  -------------   </span></span><br><span class="line">&gt;<span class="comment">//        boolean offerFirst(E e)</span></span><br><span class="line">&gt;<span class="comment">//        在此列表的开头插入指定的元素。</span></span><br><span class="line">&gt;<span class="comment">//        boolean offerLast(E e)</span></span><br><span class="line">&gt;<span class="comment">//        在此列表末尾插入指定的元素。</span></span><br><span class="line">&gt;<span class="comment">//        E peekFirst()</span></span><br><span class="line">&gt;<span class="comment">//        获取但不移除此列表的第一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line">&gt;<span class="comment">//        E peekLast()</span></span><br><span class="line">&gt;<span class="comment">//        获取但不移除此列表的最后一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line">&gt;<span class="comment">//        E pollFirst()</span></span><br><span class="line">&gt;<span class="comment">//        获取并移除此列表的第一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line">&gt;<span class="comment">//        E pollLast()</span></span><br><span class="line">&gt;<span class="comment">//        获取并移除此列表的最后一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        E pop()</span></span><br><span class="line">&gt;<span class="comment">//        从此列表所表示的堆栈处弹出一个元素。</span></span><br><span class="line">&gt;<span class="comment">//        void push(E e)</span></span><br><span class="line">&gt;<span class="comment">//        将元素推入此列表所表示的堆栈。 </span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="8-Queue"><a href="#8-Queue" class="headerlink" title="8, Queue"></a>8, Queue</h1><h2 id="8-1-Queue的特点"><a href="#8-1-Queue的特点" class="headerlink" title="8.1 Queue的特点"></a>8.1 Queue的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Queue接口是Collection的子接口</span></span><br><span class="line">&gt;<span class="comment">// 2, Queue数据结构定义队列</span></span><br><span class="line">&gt;<span class="comment">// 3, Queue存储数据有序</span></span><br><span class="line">&gt;<span class="comment">// 4, Queue允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 5, Queue不允许存储null  (LinkedList除外)</span></span><br><span class="line"></span><br><span class="line">&gt;注意: 因为如果一个队列中没有存储数据了, 我们又调用了队列的出队列方法, Queue下面的实现, 返回了一个<span class="literal">null</span>, 用来标记队列没有数据可以出队列. 所以如果我们允许队列存储<span class="literal">null</span>, 那么就会在出队列的时候返回<span class="literal">null</span>引发歧义(不知道到底是我们存储的, 还是标记结束), 为了避免这个情况出现Queue在设计的时候, 不允许存储<span class="literal">null</span>.</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="8-2-Queue的api"><a href="#8-2-Queue的api" class="headerlink" title="8.2 Queue的api"></a>8.2 Queue的api</h2><blockquote>
<p>api</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&gt;Queue是Collection的子接口, Queue具有Collection定义的所有方法</span><br><span class="line">   </span><br><span class="line">&gt;<span class="comment">// -----------Queue-----------------</span></span><br><span class="line">&gt;<span class="comment">//        boolean offer(E e)</span></span><br><span class="line">&gt;<span class="comment">//        将指定元素添加到此列表的末尾（最后一个元素）。</span></span><br><span class="line">&gt;<span class="comment">//        E peek()</span></span><br><span class="line">&gt;<span class="comment">//        获取但不移除此列表的头（第一个元素）。</span></span><br><span class="line">&gt;<span class="comment">//        E poll()</span></span><br><span class="line">&gt;<span class="comment">//        获取并移除此列表的头（第一个元素）</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="9-Deque"><a href="#9-Deque" class="headerlink" title="9, Deque"></a>9, Deque</h1><h2 id="9-1Deque的特点"><a href="#9-1Deque的特点" class="headerlink" title="9.1Deque的特点"></a>9.1Deque的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Deque接口是Queue接口的子接口</span></span><br><span class="line">&gt;<span class="comment">// 2, Deque接口在Queue定义为队列的基础上, 又表现为双端队列 和 栈</span></span><br><span class="line">&gt;<span class="comment">// 3, Deque存储数据有序</span></span><br><span class="line">&gt;<span class="comment">// 4, Deque允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 5, Deque不允许存储null  (LinkedList除外)</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="9-2-Deque的api"><a href="#9-2-Deque的api" class="headerlink" title="9.2 Deque的api"></a>9.2 Deque的api</h2><blockquote>
<p>api</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">&gt;Deque是Queue接口和Collection的子接口, Deque具有Queue和Collection定义的所有方法</span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// -----------Deque:  -------------   </span></span><br><span class="line">&gt;<span class="comment">//        boolean offerFirst(E e)</span></span><br><span class="line">&gt;<span class="comment">//        在此列表的开头插入指定的元素。</span></span><br><span class="line">&gt;<span class="comment">//        boolean offerLast(E e)</span></span><br><span class="line">&gt;<span class="comment">//        在此列表末尾插入指定的元素。</span></span><br><span class="line">&gt;<span class="comment">//        E peekFirst()</span></span><br><span class="line">&gt;<span class="comment">//        获取但不移除此列表的第一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line">&gt;<span class="comment">//        E peekLast()</span></span><br><span class="line">&gt;<span class="comment">//        获取但不移除此列表的最后一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line">&gt;<span class="comment">//        E pollFirst()</span></span><br><span class="line">&gt;<span class="comment">//        获取并移除此列表的第一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line">&gt;<span class="comment">//        E pollLast()</span></span><br><span class="line">&gt;<span class="comment">//        获取并移除此列表的最后一个元素；如果此列表为空，则返回 null。</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        E pop()</span></span><br><span class="line">&gt;<span class="comment">//        从此列表所表示的堆栈处弹出一个元素。</span></span><br><span class="line">&gt;<span class="comment">//        void push(E e)</span></span><br><span class="line">&gt;<span class="comment">//        将元素推入此列表所表示的堆栈。 </span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="10-ArrayDeque"><a href="#10-ArrayDeque" class="headerlink" title="10, ArrayDeque"></a>10, ArrayDeque</h1><h2 id="10-1-ArrayDeque的特点"><a href="#10-1-ArrayDeque的特点" class="headerlink" title="10.1 ArrayDeque的特点"></a>10.1 ArrayDeque的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, ArrayDeque是Deque接口的子实现</span></span><br><span class="line">&gt;<span class="comment">// 2, 数据结构表现:  队列, 双端队列, 栈</span></span><br><span class="line">&gt;<span class="comment">// 3, 底层结构是数组: 循环数组</span></span><br><span class="line">&gt;<span class="comment">// 4, 默认初始长度:16;  默认扩容机制:2倍 --&gt; 数组长度保持2的幂值</span></span><br><span class="line">&gt;<span class="comment">// 5, 存储元素有序</span></span><br><span class="line">&gt;<span class="comment">// 6, 允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 7, 不允许存储null</span></span><br><span class="line">&gt;<span class="comment">// 8, 线程不安全</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 注意: 我们可以在ArrayDeque的构造方法中, 给他指明数组长度, 但是当我们给他一个长度x (x大于等于8), 它会把ArrayDeque的底层数组变成一个长度为大于给定的x的最小的2的幂值</span></span><br><span class="line">&gt;<span class="comment">// 注意: 但是当我们给他一个长度x 小于8, 底层构建数组长度是8</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 10 -&gt; 16</span></span><br><span class="line">&gt;<span class="comment">// 20 -&gt; 32</span></span><br><span class="line">&gt;<span class="comment">// 40 -&gt; 64</span></span><br><span class="line">&gt;<span class="comment">// 32 -&gt; 64</span></span><br></pre></td></tr></table></figure>

</blockquote>
<h1 id="11-BlockingQueue"><a href="#11-BlockingQueue" class="headerlink" title="11, BlockingQueue"></a>11, BlockingQueue</h1><h2 id="11-1-BlockingQueue的注意事项"><a href="#11-1-BlockingQueue的注意事项" class="headerlink" title="11.1 BlockingQueue的注意事项"></a>11.1 BlockingQueue的注意事项</h2><blockquote>
<p>1, BlockingQueue: 阻塞队列;  什么是阻塞队列? 阻塞队列的应用场景?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;阻塞队列:</span><br><span class="line">&gt;<span class="comment">// 一个大小容量有限的队列</span></span><br><span class="line">&gt;<span class="comment">// 添加操作的时候, 队列添加满了, 添加线程等待</span></span><br><span class="line">&gt;<span class="comment">// 删除操作的时候, 队列删除空了, 删除线程等待</span></span><br><span class="line"></span><br><span class="line">&gt;应用场景: 缓存</span><br><span class="line">&gt;<span class="comment">// 线程池</span></span><br></pre></td></tr></table></figure>

<p>2, BlockingQueue的哪些方法是阻塞的?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// BlockingQueue关于添加和删除的方法有四类:</span></span><br><span class="line">&gt;<span class="comment">//       不满足条件抛出异常: add, remove</span></span><br><span class="line">&gt;<span class="comment">//       不满足条件返回特殊值: offer(布尔值), poll(null)</span></span><br><span class="line">&gt;<span class="comment">//       不满足条件一直阻塞: put, take</span></span><br><span class="line">&gt;<span class="comment">//       在指定时间内阻塞:  超时的offer/poll</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="12-Map"><a href="#12-Map" class="headerlink" title="12, Map"></a>12, Map</h1><h2 id="12-1-Map的特点"><a href="#12-1-Map的特点" class="headerlink" title="12.1 Map的特点"></a>12.1 Map的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Map是Map集合体系的顶级接口</span></span><br><span class="line">&gt;<span class="comment">// 2, Map是一个存储映射数据(key-value; 键值对)的数据容器</span></span><br><span class="line">&gt;<span class="comment">// 3, Map的一些子实现有序, 一些子实现存储数据无序: (指key)</span></span><br><span class="line">&gt;<span class="comment">// 4, Map不允许存储重复数据: (指key)</span></span><br><span class="line">&gt;<span class="comment">// 5, Map的一些子实现允许存储null, Map的一些子实现不允许存储null: (指key)</span></span><br><span class="line"></span><br><span class="line">&gt;注意: Map没有办法<span class="string">&#x27;直接&#x27;</span>使用foreach循环, 因为Map和Collection不一样( Collection&lt;E&gt; <span class="keyword">extends</span> <span class="title class_">Iterable</span>&lt;E&gt;), Map从接口名上不是Iterable子接口.</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="12-2-Map的api"><a href="#12-2-Map的api" class="headerlink" title="12.2 Map的api"></a>12.2 Map的api</h2><blockquote>
<p>api</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">       <span class="comment">// ----添加删除相关----------------</span></span><br><span class="line">&gt;<span class="comment">//        V put(K key, V value): 添加方法</span></span><br><span class="line">&gt;<span class="comment">//        void putAll(Map&lt;? extends K,? extends V&gt; m): 添加所有</span></span><br><span class="line">&gt;<span class="comment">//        V remove(Object key): 根据key删除键值对</span></span><br><span class="line">&gt;<span class="comment">//        V get(Object key): 根据key获取key对应value</span></span><br><span class="line">&gt;<span class="comment">//        boolean containsKey(Object key): 查找key是否存在</span></span><br><span class="line">&gt;<span class="comment">//        boolean containsValue(Object value): 查找value是否存在</span></span><br><span class="line">       <span class="comment">// -----辅助方法------------------</span></span><br><span class="line">&gt;<span class="comment">//        int size()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射中的键-值映射关系数。</span></span><br><span class="line">&gt;<span class="comment">//        int hashCode()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射的哈希码值。</span></span><br><span class="line">&gt;<span class="comment">//        boolean isEmpty()</span></span><br><span class="line">&gt;<span class="comment">//        如果此映射未包含键-值映射关系，则返回 true。</span></span><br><span class="line">&gt;<span class="comment">//        boolean equals(Object o)</span></span><br><span class="line">&gt;<span class="comment">//        比较指定的对象与此映射是否相等。</span></span><br><span class="line">&gt;<span class="comment">//        void clear()</span></span><br><span class="line">&gt;<span class="comment">//        从此映射中移除所有映射关系（可选操作）。</span></span><br><span class="line">       <span class="comment">// -----特殊方法(在实际使用的时候,主要是用来帮助我们遍历Map数据)-------</span></span><br><span class="line">&gt;<span class="comment">//        Set&lt;K&gt; keySet()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射中包含的键的 Set 视图。</span></span><br><span class="line">   <span class="comment">//        Collection&lt;V&gt; values()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射中包含的值的 Collection 视图。</span></span><br><span class="line">&gt;<span class="comment">//        Set&lt;Map.Entry&lt;K,V&gt;&gt; entrySet()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射中包含的映射关系的 Set 视图。</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="13-HashMap"><a href="#13-HashMap" class="headerlink" title="13, HashMap"></a>13, HashMap</h1><h2 id="13-1-HashMap的底层结构"><a href="#13-1-HashMap的底层结构" class="headerlink" title="13.1 HashMap的底层结构"></a>13.1 HashMap的底层结构</h2><blockquote>
<p>HashMap的底层机构:  数组+链表+红黑树  (jdk1.8)</p>
<p>​                                        数组+链表(jdk1.8之前)</p>
</blockquote>
<h2 id="13-2-HashMap的特点"><a href="#13-2-HashMap的特点" class="headerlink" title="13.2 HashMap的特点"></a>13.2 HashMap的特点</h2><blockquote>
<p>1, 基本特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, HashMap是Map接口的子实现</span></span><br><span class="line">&gt;<span class="comment">// 2, HashMap的底层结构:  数组+链表+红黑树(红黑树是在Jdk1.8时候引入的结构)</span></span><br><span class="line">&gt;<span class="comment">// 3, 数组的默认初始长度16,  扩容机制2倍, 加载因子是0.75</span></span><br><span class="line">&gt;<span class="comment">// 4, HashMap存储数据无序</span></span><br><span class="line">&gt;<span class="comment">// 5, HashMap不允许存储重复的key (什么叫重复? )</span></span><br><span class="line">&gt;<span class="comment">// 6, HashMap允许存储null作为key</span></span><br><span class="line">&gt;<span class="comment">// 7, </span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>2, 加载因子</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// HashMap底层是一个数组+链表+红黑树的结构, 在存储数据的时候, 我们需要根据存储的元素数据量进行数组扩容, 当HashMap中存储的数据量大于阈值, 就要扩容.</span></span><br><span class="line"></span><br><span class="line">阈值 = 数组长度 * 加载因子</span><br><span class="line"><span class="number">12</span>   = <span class="number">16</span>  *  <span class="number">0.75</span></span><br></pre></td></tr></table></figure>

<p>3, HashMap底层持有数组的类型</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// HashMap底层持有的数据, 是一个Node类型的数组</span></span><br><span class="line"></span><br><span class="line">&gt;Node[] table; <span class="comment">// HashMap的底层数组</span></span><br><span class="line">&gt;<span class="keyword">class</span> <span class="title class_">Node</span>&#123;</span><br><span class="line">   key,</span><br><span class="line">   value,</span><br><span class="line">   hash, <span class="comment">// key计算的hash值</span></span><br><span class="line">   next  <span class="comment">// 后续构建链表</span></span><br><span class="line">&gt;&#125;</span><br></pre></td></tr></table></figure>

<p>4, 给HashMap指定初始长度</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 如果我们在构造方法中, 提供一个长度, 以供HashMap创建底层数组, 假如我们提供一个数据X, 它会创建一个大于等于X的长度的最小的2的幂值作为数组长度</span></span><br><span class="line"></span><br><span class="line">&gt;注意: 结合给定值变成<span class="number">2</span>的幂值, 以及数组长度默认是<span class="number">16</span>, 扩容机制扩为原来的<span class="number">2</span>倍 --&gt; 数组长度永远是<span class="number">2</span>的幂值</span><br></pre></td></tr></table></figure>

<p>5, HashMap中, 每一个key的Hash值的取法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// key如果是null, hash值0</span></span><br><span class="line">&gt;<span class="comment">// key不是null:    获得key的hashCode 并且 异或上 key的hashCode向right移动16位</span></span><br><span class="line"></span><br><span class="line">&gt;(key == <span class="literal">null</span>) ? <span class="number">0</span> : (h = key.hashCode()) ^ (h &gt;&gt;&gt; <span class="number">16</span>);</span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 我们希望在使用HashMap存储数据的时候, 每一个key-value的key经过计算之后,散列的下标位置都不同.(理想状态)</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 因为数组长度是2的幂值, 希望key散列的下标位置都不同, 等价于希望key的hash低位都不要一样</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// 希望不同key的hash值低位尽可能不要相同</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// (h = key.hashCode()) ^ (h &gt;&gt;&gt; 16);让hashCode参数, 高位和低位混合,得到hash值</span></span><br></pre></td></tr></table></figure>

<p>6, 在HashMap中怎么判断两次添加的key-value数据的key重复了?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;判断的依据</span><br><span class="line">&gt;<span class="comment">// 1, 首要要求两个key的hash值要一样</span></span><br><span class="line">&gt;<span class="comment">// 2, 在满足hash值一样之后,  还要要求: 两个key直接相等 或者 相equals</span></span><br><span class="line"></span><br><span class="line">&gt;p.hash == hash &amp;&amp;  ((k = p.key) == key || (key != <span class="literal">null</span> &amp;&amp; key.equals(k)))</span><br></pre></td></tr></table></figure>

<p>7, 如果在HashMap添加数据的时候, key重复了</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;当key重复的时候, 新添加的key-value数据的value会替换旧的key-value数据的value</span><br></pre></td></tr></table></figure>

<p>8, 链表什么时候转化为红黑树? </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 当HashMap的某个下标位置, 链表长度超过8,达到9个结点的时候(算上新添加的结点), 就要由链表转化为红黑树.</span></span><br><span class="line">&gt;<span class="comment">// 一般我们称为链表转化为红黑树的阈值是8.</span></span><br></pre></td></tr></table></figure>

<p>9, 在HashMap中, 链表长度超过8达到9, 一定会由链表转化为红黑树吗?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 不一定</span></span><br><span class="line">&gt;<span class="comment">// 如果HashMap的底层数组长度是小于64的话,  链表长度超过8达到9, 不是转化为红黑树, 而是去扩容底层数组</span></span><br><span class="line">&gt;<span class="comment">// 如果HashMap的底层数组长度是大于等于64的话,  链表长度超过8达到9, 才会转化为红黑树.</span></span><br></pre></td></tr></table></figure>

<p>10, 红黑树什么时候转化回链表?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&gt;删除</span><br><span class="line">&gt;<span class="comment">// 如果HashMap删除的数据在红黑树上, 当删除的时候红黑树的根结点/根的左右结点/根的左结点的左结点, 这四个结点有一个是null , 要由红黑树转化回链表.</span></span><br><span class="line">&gt;root == <span class="literal">null</span> || root.right == <span class="literal">null</span> || (rl = root.left) == <span class="literal">null</span> || rl.left == <span class="literal">null</span>) </span><br><span class="line"></span><br><span class="line">&gt;扩容    </span><br><span class="line">&gt;<span class="comment">// 扩容的时候, 红黑树要重新在HashMap的数组上进行散列, 只会散列到两个位置, 任一位置的数据量小于等于6的话, 都要由红黑树转化回链表.</span></span><br></pre></td></tr></table></figure>

<p>11, 扩容问题: 数据重新散列的问题</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 在扩容的时候, 在旧数组的x下标位置存储的key-value数据, 经过扩容之后, 要么还在x位置, 要么在旧数组长度+x位置;  只有这两个选择.</span></span><br></pre></td></tr></table></figure>

<p>12, HashMap中红黑树的一些问题</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, HashMap什么时候引入的红黑树? jdk1.8</span></span><br><span class="line">&gt;<span class="comment">// 2, HashMap为什么要引入红黑树? </span></span><br><span class="line">&gt;<span class="comment">// 3, HashMap中的红黑树, 是按照什么比较大小确定左右方向的? 按照hash值比较大小确定方向</span></span><br></pre></td></tr></table></figure>

<p>13, 为什么链表转化为红黑树阈值是8, 而红黑树转化为链表阈值是6? (可能会问)(这个问题的本身就有问题) </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 如果阈值设为一样, 有可能红黑树和链表会在不断的添加和扩容过程中反复转化. 所以我们预留了一部分范围缓冲</span></span><br></pre></td></tr></table></figure>

<p>14, 如果一份key-value数据已经添加到HashMap上了, 就不要通过key的引用直接修改这个key, “有可能’’导致这个key值再也不可访问</p>
</blockquote>
<h3 id="HashMap的添加数据的流程"><a href="#HashMap的添加数据的流程" class="headerlink" title="HashMap的添加数据的流程"></a>HashMap的添加数据的流程</h3><blockquote>
<p>流程</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, 有一份key-value数据, 要添加的HashMap中</span></span><br><span class="line">&gt;<span class="comment">// 2, 取出key 计算 hash值 ((h = key.hashCode()) ^ (h &gt;&gt;&gt; 16);)</span></span><br><span class="line"> 取移位和异或运算的原因是希望充分散列/尽量不冲突</span><br><span class="line">&gt;<span class="comment">// 3, 用计算的hash值和数组长度取模: (n - 1) &amp; hash</span></span><br><span class="line">推出一个隐含的结论, 在取模计算中 只有hash值的低位会起效果</span><br><span class="line">&gt;<span class="comment">// 4, 根据上一步计算的下标, 判断这个下标位置是否已经存储了内容, 如果没有存储内容, 直接创建一个结点存储到这个下标位置</span></span><br><span class="line">     结点是Node类型, 包含: key,value, hash,next四个参数</span><br><span class="line">&gt;<span class="comment">// 5,  根据上一步(第3)计算的下标, 这个下标位置可能已经存储了元素:  先判断是否重复</span></span><br><span class="line">      hash一样; 并且,  两个key要么直接相等, 要么相equals</span><br><span class="line">		p.hash == hash &amp;&amp; ((k = p.key) == key || (key != <span class="literal">null</span> &amp;&amp; key.equals(k)))</span><br><span class="line">&gt;<span class="comment">//      5.1 如果key值重复了, 新的key-value的value值覆盖旧值   </span></span><br><span class="line">&gt;<span class="comment">//      5.2 如果key值不重复, 接着按照链表向下比较, 在遍历链表的过程中还是判断链表中的结点是否重复, (重复了, 新值覆盖旧值)</span></span><br><span class="line">&gt;<span class="comment">//          如果在这个链表比较的过程中, 一直不重复, 把这份新的key-value数据,构建一个结点,添加到这个链表的尾部</span></span><br><span class="line">&gt;<span class="comment">// 6, 如果在这个下标位置, 不重复, 添加(构建链表)(5.2步骤), 如果添加一个元素之后, 导致链表出长度(超过8, 达到9), 那么添加完成之后, 这个链表要转化为红黑树</span></span><br><span class="line">&gt;<span class="comment">//         如果转化红黑树的过程中, 发现数组长度小于64, 选择扩容(元素重新按照新长度散列问题), 而非转化为红黑树</span></span><br><span class="line">    </span><br><span class="line">&gt;<span class="comment">// 7, 假设上述步骤添加成功一份key-value数据:  有可能引起扩容 (整体存储的数据超过阈值)</span></span><br><span class="line">          <span class="number">1</span></span><br><span class="line">&gt;<span class="comment">// 8, 上述所有的扩容, 都有可能导致原本数组某个位置如果有红黑树, 红黑树被拆成两部分(低位和高位), 任一位置结点数变少, 又有可能导致红黑树转化为链表</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="13-3-HashMap的构造方法"><a href="#13-3-HashMap的构造方法" class="headerlink" title="13.3 HashMap的构造方法"></a>13.3 HashMap的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&gt;HashMap() </span><br><span class="line">         构造一个具有默认初始容量 (<span class="number">16</span>) 和默认加载因子 (<span class="number">0.75</span>) 的空 HashMap。 </span><br><span class="line">&gt;HashMap(<span class="type">int</span> initialCapacity) </span><br><span class="line">         构造一个带指定初始容量和默认加载因子 (<span class="number">0.75</span>) 的空 HashMap。 </span><br><span class="line">&gt;HashMap(<span class="type">int</span> initialCapacity, <span class="type">float</span> loadFactor) </span><br><span class="line">         构造一个带指定初始容量和加载因子的空 HashMap。 </span><br><span class="line">&gt;HashMap(Map&lt;? <span class="keyword">extends</span> <span class="title class_">K</span>,? <span class="keyword">extends</span> <span class="title class_">V</span>&gt; m) </span><br><span class="line">         构造一个映射关系与指定 Map 相同的新 HashMap。 </span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="13-4-HashMap的api"><a href="#13-4-HashMap的api" class="headerlink" title="13.4 HashMap的api"></a>13.4 HashMap的api</h2><blockquote>
<p>HashMap没有在Map接口的基础上额外定义什么api</p>
</blockquote>
<h1 id="14-LinkedHashMap"><a href="#14-LinkedHashMap" class="headerlink" title="14, LinkedHashMap"></a>14, LinkedHashMap</h1><h2 id="14-1-LinkedHashMap的特点"><a href="#14-1-LinkedHashMap的特点" class="headerlink" title="14.1 LinkedHashMap的特点"></a>14.1 LinkedHashMap的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, LinkedHashMap是HashMap的子类</span></span><br><span class="line">&gt;<span class="comment">// 2, LinkedHashMap底层基本上完全复用了HashMap的结构 --&gt; LinkedHashMap的特点基本上和HashMap一样 (结构: 数组+链表+红黑树, hash, 重复)</span></span><br><span class="line">&gt;<span class="comment">// 3, LinkedHashMap在HashMap的基础上额外定义了一个双向链表, 用以保证迭代顺序 (重要)</span></span><br><span class="line">&gt;<span class="comment">// 4, LinkedHashMap存储数据有序</span></span><br><span class="line">&gt;<span class="comment">// 5, LinkedHashMap不允许存储重复数据·</span></span><br><span class="line">&gt;<span class="comment">// 6, LinkedHashMap允许存储null</span></span><br><span class="line">&gt;<span class="comment">// 7, 线程不安全</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="14-2-LinkedHashMap的构造方法"><a href="#14-2-LinkedHashMap的构造方法" class="headerlink" title="14.2 LinkedHashMap的构造方法"></a>14.2 LinkedHashMap的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&gt;LinkedHashMap() </span><br><span class="line">         构造一个带默认初始容量 (<span class="number">16</span>) 和加载因子 (<span class="number">0.75</span>) 的空插入顺序 LinkedHashMap 实例。 </span><br><span class="line">&gt;LinkedHashMap(<span class="type">int</span> initialCapacity) </span><br><span class="line">         构造一个带指定初始容量和默认加载因子 (<span class="number">0.75</span>) 的空插入顺序 LinkedHashMap 实例。 </span><br><span class="line">&gt;LinkedHashMap(<span class="type">int</span> initialCapacity, <span class="type">float</span> loadFactor) </span><br><span class="line">         构造一个带指定初始容量和加载因子的空插入顺序 LinkedHashMap 实例。 </span><br><span class="line">&gt;LinkedHashMap(<span class="type">int</span> initialCapacity, <span class="type">float</span> loadFactor, <span class="type">boolean</span> accessOrder) </span><br><span class="line">         构造一个带指定初始容量、加载因子和排序模式的空 LinkedHashMap 实例。 </span><br><span class="line">&gt;LinkedHashMap(Map&lt;? <span class="keyword">extends</span> <span class="title class_">K</span>,? <span class="keyword">extends</span> <span class="title class_">V</span>&gt; m) </span><br><span class="line">         构造一个映射关系与指定映射相同的插入顺序 LinkedHashMap 实例。 </span><br><span class="line"></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="14-3-LinkedHashMap的api"><a href="#14-3-LinkedHashMap的api" class="headerlink" title="14.3 LinkedHashMap的api"></a>14.3 LinkedHashMap的api</h2><blockquote>
<p>LinkedHashMap没有在Map接口的基础上额外定义什么api (甚至LinkedHashMap的api基本上完全复用父类HashMap的实现)</p>
</blockquote>
<h1 id="15-Hashtable"><a href="#15-Hashtable" class="headerlink" title="15, Hashtable"></a>15, Hashtable</h1><h2 id="15-1-Hashtable的特点"><a href="#15-1-Hashtable的特点" class="headerlink" title="15.1 Hashtable的特点"></a>15.1 Hashtable的特点</h2><blockquote>
<p>特点: (Hashtable完全用不到, 只会面试中被问到, 和HashMap做对比)</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Hashtbale是Map的子实现</span></span><br><span class="line">&gt;<span class="comment">// 2, Hashtable底层结构是: 数组+链表  (和HashMap在jdk1.8之前一样)</span></span><br><span class="line">&gt;<span class="comment">// 3, Hashtable底层数组长度11, 扩容机制2倍+1.</span></span><br><span class="line">&gt;<span class="comment">// 4, Hashtable存储数据无序</span></span><br><span class="line">&gt;<span class="comment">// 5, Hashtable不允许存储重复数据 (重复的定义和HashMap一样)</span></span><br><span class="line">&gt;<span class="comment">// 6, Hashtable不允许存储null作为key, 也不允许存储null作为value</span></span><br><span class="line">&gt;<span class="comment">// 7, 线程安全.</span></span><br><span class="line">&gt;<span class="comment">// 8, jdk1.0时候出现, HashMap是1.2出现 (HashMap出现就是为了取代Hashtable)</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="16-Properties-了解"><a href="#16-Properties-了解" class="headerlink" title="16, Properties: 了解"></a>16, Properties: 了解</h1><blockquote>
<p>面试不会问, 工作用的不多. 后面学的一些知识和这个相关.</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Properties是Hashtable子类</span></span><br><span class="line">&gt;<span class="comment">// 2, 一般我们使用Properties的时候, 是为了持久化.或者加载配置文件配置项.</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="17-TreeMap"><a href="#17-TreeMap" class="headerlink" title="17, TreeMap"></a>17, TreeMap</h1><h2 id="17-1-TreeMap的特点"><a href="#17-1-TreeMap的特点" class="headerlink" title="17.1 TreeMap的特点"></a>17.1 TreeMap的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, TreeMap是Map接口子实现</span></span><br><span class="line">&gt;<span class="comment">// 2, TreeMap数据结构表现是红黑树</span></span><br><span class="line">&gt;<span class="comment">// 3, TreeMap存储数据大小有序</span></span><br><span class="line">&gt;<span class="comment">// 4, TreeMap不允许存储重复数据  (什么叫重复?  key的大小一样)</span></span><br><span class="line">&gt;<span class="comment">// 5, TreeMap不允许null作为key</span></span><br><span class="line">&gt;<span class="comment">// 6, TreeMap线程不安全</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="17-1-TreeMap的构造方法"><a href="#17-1-TreeMap的构造方法" class="headerlink" title="17.1 TreeMap的构造方法"></a>17.1 TreeMap的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&gt;TreeMap() </span><br><span class="line">         使用键的自然顺序构造一个新的、空的树映射。 </span><br><span class="line">&gt;TreeMap(Comparator&lt;? <span class="built_in">super</span> K&gt; comparator) </span><br><span class="line">         构造一个新的、空的树映射，该映射根据给定比较器进行排序。 </span><br><span class="line">   </span><br><span class="line">&gt;TreeMap(Map&lt;? <span class="keyword">extends</span> <span class="title class_">K</span>,? <span class="keyword">extends</span> <span class="title class_">V</span>&gt; m) </span><br><span class="line">         构造一个与给定映射具有相同映射关系的新的树映射，该映射根据其键的自然顺序 进行排序。 </span><br><span class="line">&gt;TreeMap(SortedMap&lt;K,? <span class="keyword">extends</span> <span class="title class_">V</span>&gt; m) </span><br><span class="line">         构造一个与指定有序映射具有相同映射关系和相同排序顺序的新的树映射。 </span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="17-2-TreeMap的api"><a href="#17-2-TreeMap的api" class="headerlink" title="17.2 TreeMap的api"></a>17.2 TreeMap的api</h2><blockquote>
<p>api</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">//  -----Map接口定义的api---------</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">// ------自己的新的关于大小操作的api---------------------</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; ceilingEntry(K key): 返回大于等于给定值的键值对</span></span><br><span class="line">&gt;<span class="comment">//        K ceilingKey(K key): 返回大于等于给定值的key</span></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; floorEntry(K key): 返回小于等于给定值的键值对</span></span><br><span class="line">&gt;<span class="comment">//        K floorKey(K key): 返回小于等于给定值的key</span></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; higherEntry(K key): 返回大于给定值的键值对</span></span><br><span class="line">&gt;<span class="comment">//        K higherKey(K key): 返回大于给定值的key</span></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; lowerEntry(K key): 返回小于给定值的键值对</span></span><br><span class="line">&gt;<span class="comment">//        K lowerKey(K key): 返回小于给定值的key</span></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; firstEntry(): 获得第一份键值对()最小</span></span><br><span class="line">&gt;<span class="comment">//        K firstKey(): 获得第一份key()最小</span></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; lastEntry(): 获得最后一份键值对(最大)</span></span><br><span class="line">&gt;<span class="comment">//        K lastKey(): 获得最后一份key(最大)</span></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; pollFirstEntry(): 删除第一份数据(最小)</span></span><br><span class="line">&gt;<span class="comment">//        Map.Entry&lt;K,V&gt; pollLastEntry(): 删除最后一份数据(最大)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        NavigableSet&lt;K&gt; navigableKeySet()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射中所包含键的 NavigableSet 视图。</span></span><br><span class="line">&gt;<span class="comment">//        如果此映射为指定值映射一个或多个键，则返回 true。</span></span><br><span class="line">&gt;<span class="comment">//        NavigableSet&lt;K&gt; descendingKeySet()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射中所包含键的逆序 NavigableSet 视图。</span></span><br><span class="line">&gt;<span class="comment">//        NavigableMap&lt;K,V&gt; descendingMap()</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射中所包含映射关系的逆序视图。</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&gt;<span class="comment">//        NavigableMap&lt;K,V&gt; subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射的部分视图，其键的范围从 fromKey 到 toKey。</span></span><br><span class="line">&gt;<span class="comment">//        SortedMap&lt;K,V&gt; subMap(K fromKey, K toKey)</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射的部分视图，其键值的范围从 fromKey（包括）到 toKey（不包括）。</span></span><br><span class="line">&gt;<span class="comment">//        SortedMap&lt;K,V&gt; tailMap(K fromKey)</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射的部分视图，其键大于等于 fromKey。</span></span><br><span class="line">&gt;<span class="comment">//        NavigableMap&lt;K,V&gt; tailMap(K fromKey, boolean inclusive)</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射的部分视图，其键大于（或等于，如果 inclusive 为 true）fromKey。</span></span><br><span class="line">&gt;<span class="comment">//        SortedMap&lt;K,V&gt; headMap(K toKey)</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射的部分视图，其键值严格小于 toKey。</span></span><br><span class="line">&gt;<span class="comment">//        NavigableMap&lt;K,V&gt; headMap(K toKey, boolean inclusive)</span></span><br><span class="line">&gt;<span class="comment">//        返回此映射的部分视图，其键小于（或等于，如果 inclusive 为 true）toKey。</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h1 id="18-Set"><a href="#18-Set" class="headerlink" title="18, Set"></a>18, Set</h1><h2 id="18-1-Set-的特点"><a href="#18-1-Set-的特点" class="headerlink" title="18.1 Set 的特点"></a>18.1 Set 的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="comment">// 1, Set接口是Collection的子接口</span></span><br><span class="line">&gt;<span class="comment">// 2, Set接口数据结构: 集合</span></span><br><span class="line">&gt;<span class="comment">// 3, Set的一些子实现有序(LinkedHashSet, TreeSet), 有一些子实现是无序的</span></span><br><span class="line">&gt;<span class="comment">// 4, Set都不允许存储重复数据</span></span><br><span class="line">&gt;<span class="comment">// 5, Set的一些子实现允许存储null(HashSet, LinkedHashSet) 有一些子实现不允许存储null(TreeSet)</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="18-2-Set的api"><a href="#18-2-Set的api" class="headerlink" title="18.2 Set的api"></a>18.2 Set的api</h2><blockquote>
<p>Set的api和Collection一模一样</p>
</blockquote>
<h1 id="19-HashSet"><a href="#19-HashSet" class="headerlink" title="19, HashSet"></a>19, HashSet</h1><h2 id="19-1-HashSet的特点"><a href="#19-1-HashSet的特点" class="headerlink" title="19.1 HashSet的特点"></a>19.1 HashSet的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="number">1</span>, HashSet是Set的子实现</span><br><span class="line">&gt;<span class="number">2</span>, HashSet底层持有了一个HashMap对象, 我们添加到HashSet的数据实际上都添加到底层持有的HashMap的key上了.</span><br><span class="line">&gt;<span class="number">3</span>, HashSet的特点基本上要遵照于HashMap的key的特点</span><br><span class="line">&gt;<span class="number">4</span>, 存储数据无序</span><br><span class="line">&gt;<span class="number">5</span>, 不允许存储重复数据(   重复的依据: hashCode, equals )</span><br><span class="line">&gt;<span class="number">6</span>, 允许存储<span class="literal">null</span></span><br><span class="line">&gt;<span class="number">7</span>, 线程不安全</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="19-2-HashSet的构造方法"><a href="#19-2-HashSet的构造方法" class="headerlink" title="19.2 HashSet的构造方法"></a>19.2 HashSet的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&gt;HashSet() </span><br><span class="line">    构造一个新的空 set，其底层 HashMap 实例的默认初始容量是 <span class="number">16</span>，加载因子是 <span class="number">0.75</span>。 </span><br><span class="line">&gt;HashSet(Collection&lt;? <span class="keyword">extends</span> <span class="title class_">E</span>&gt; c) </span><br><span class="line">    构造一个包含指定 collection 中的元素的新 set。 </span><br><span class="line">&gt;HashSet(<span class="type">int</span> initialCapacity) </span><br><span class="line">    构造一个新的空 set，其底层 HashMap 实例具有指定的初始容量和默认的加载因子（<span class="number">0.75</span>）。 </span><br><span class="line">&gt;HashSet(<span class="type">int</span> initialCapacity, <span class="type">float</span> loadFactor) </span><br><span class="line">    构造一个新的空 set，其底层 HashMap 实例具有指定的初始容量和指定的加载因子。 </span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="19-3-HashSet的api"><a href="#19-3-HashSet的api" class="headerlink" title="19.3 HashSet的api"></a>19.3 HashSet的api</h2><blockquote>
<p>HashSet 并没有在Set&#x2F;Collection的基础上额外定义什么api, 完全参照Collection定义的api</p>
</blockquote>
<h1 id="20-LinkedHashSet"><a href="#20-LinkedHashSet" class="headerlink" title="20, LinkedHashSet"></a>20, LinkedHashSet</h1><h2 id="20-1-LinkedHashSet的特点"><a href="#20-1-LinkedHashSet的特点" class="headerlink" title="20.1 LinkedHashSet的特点"></a>20.1 LinkedHashSet的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="number">1</span>, LinkedHashSet是HashSet的子类</span><br><span class="line">&gt;<span class="number">2</span>, LInkedHashSet底层持有了一个LinkedHashMap对象(向LInkedHashSet添加的数据,都加到底层的LinkedHashMap的key上)</span><br><span class="line">&gt;<span class="number">3</span>, LinkedHashSet的特点和LinkedHashMap的key一直</span><br><span class="line">&gt;<span class="number">4</span>, LinkedHashSet存储数据有序</span><br><span class="line">&gt;<span class="number">5</span>, 不允许存储重复数据</span><br><span class="line">&gt;<span class="number">6</span>, 允许存储<span class="literal">null</span></span><br><span class="line">&gt;<span class="number">7</span>, 线程不安全</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="20-2-LinkedHashSet的构造方法"><a href="#20-2-LinkedHashSet的构造方法" class="headerlink" title="20.2 LinkedHashSet的构造方法"></a>20.2 LinkedHashSet的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&gt;LinkedHashSet() </span><br><span class="line">    构造一个带默认初始容量 (<span class="number">16</span>) 和加载因子 (<span class="number">0.75</span>) 的新空链接哈希 set。 </span><br><span class="line">&gt;LinkedHashSet(Collection&lt;? <span class="keyword">extends</span> <span class="title class_">E</span>&gt; c) </span><br><span class="line">    构造一个与指定 collection 中的元素相同的新链接哈希 set。 </span><br><span class="line">&gt;LinkedHashSet(<span class="type">int</span> initialCapacity) </span><br><span class="line">    构造一个带指定初始容量和默认加载因子 (<span class="number">0.75</span>) 的新空链接哈希 set。 </span><br><span class="line">&gt;LinkedHashSet(<span class="type">int</span> initialCapacity, <span class="type">float</span> loadFactor) </span><br><span class="line">    构造一个带有指定初始容量和加载因子的新空链接哈希 set。 </span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="20-3-LinkedHashSet的api"><a href="#20-3-LinkedHashSet的api" class="headerlink" title="20.3 LinkedHashSet的api"></a>20.3 LinkedHashSet的api</h2><blockquote>
<p>LinkedHashSet 并没有在HashSet&#x2F;Set&#x2F;Collection的基础上额外定义什么api, 完全参照Collection定义的api</p>
</blockquote>
<h1 id="21-TreeSet"><a href="#21-TreeSet" class="headerlink" title="21, TreeSet"></a>21, TreeSet</h1><h2 id="21-1-TreeSet的特点"><a href="#21-1-TreeSet的特点" class="headerlink" title="21.1 TreeSet的特点"></a>21.1 TreeSet的特点</h2><blockquote>
<p>特点</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="number">1</span>, TreeSet是Set的子实现</span><br><span class="line">&gt;<span class="number">2</span>, TreeSet底层持有了一个TreeMap对象</span><br><span class="line">&gt;<span class="number">3</span>, TreeSet的特点和TreeMap的key保持一直</span><br><span class="line">&gt;<span class="number">4</span>, TreeSet存储数据: 大小有序</span><br><span class="line">&gt;<span class="number">5</span>, TreeSet不允许存储重复数据:  (大小重复)</span><br><span class="line">&gt;<span class="number">6</span>, TreeSet不允许存储<span class="literal">null</span></span><br><span class="line">&gt;<span class="number">7</span>, 线程不安全</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="21-2-TreeSet的构造方法"><a href="#21-2-TreeSet的构造方法" class="headerlink" title="21.2 TreeSet的构造方法"></a>21.2 TreeSet的构造方法</h2><blockquote>
<p>构造方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&gt;TreeSet() </span><br><span class="line">    构造一个新的空 set，该 set 根据其元素的自然顺序进行排序。 </span><br><span class="line">&gt;TreeSet(Comparator&lt;? <span class="built_in">super</span> E&gt; comparator) </span><br><span class="line">    构造一个新的空 TreeSet，它根据指定比较器进行排序。 </span><br><span class="line">&gt;TreeSet(Collection&lt;? <span class="keyword">extends</span> <span class="title class_">E</span>&gt; c) </span><br><span class="line">    构造一个包含指定 collection 元素的新 TreeSet，它按照其元素的自然顺序进行排序。 </span><br><span class="line">&gt;TreeSet(SortedSet&lt;E&gt; s) </span><br><span class="line">    构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。 </span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="21-3-TreeSet的api"><a href="#21-3-TreeSet的api" class="headerlink" title="21.3 TreeSet的api"></a>21.3 TreeSet的api</h2><blockquote>
<p>api</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line">&gt;<span class="type">boolean</span> <span class="title function_">add</span><span class="params">(E e)</span> </span><br><span class="line">    将指定的元素添加到此 set（如果该元素尚未存在于 set 中）。 </span><br><span class="line">&gt;<span class="type">boolean</span> <span class="title function_">addAll</span><span class="params">(Collection&lt;? extends E&gt; c)</span> </span><br><span class="line">    将指定 collection 中的所有元素添加到此 set 中。 </span><br><span class="line">&gt;E <span class="title function_">ceiling</span><span class="params">(E e)</span> </span><br><span class="line">    返回此 set 中大于等于给定元素的最小元素；如果不存在这样的元素，则返回 <span class="literal">null</span>。 </span><br><span class="line">&gt;<span class="keyword">void</span> <span class="title function_">clear</span><span class="params">()</span> </span><br><span class="line">    移除此 set 中的所有元素。 </span><br><span class="line">&gt;Object <span class="title function_">clone</span><span class="params">()</span> </span><br><span class="line">    返回 TreeSet 实例的浅表副本。 </span><br><span class="line">&gt;Comparator&lt;? <span class="built_in">super</span> E&gt; comparator() </span><br><span class="line">    返回对此 set 中的元素进行排序的比较器；如果此 set 使用其元素的自然顺序，则返回 <span class="literal">null</span>。 </span><br><span class="line">&gt;<span class="type">boolean</span> <span class="title function_">contains</span><span class="params">(Object o)</span> </span><br><span class="line">    如果此 set 包含指定的元素，则返回 <span class="literal">true</span>。 </span><br><span class="line">&gt;Iterator&lt;E&gt; <span class="title function_">descendingIterator</span><span class="params">()</span> </span><br><span class="line">    返回在此 set 元素上按降序进行迭代的迭代器。 </span><br><span class="line">&gt;NavigableSet&lt;E&gt; de 	<span class="title function_">scendingSet</span><span class="params">()</span> </span><br><span class="line">    返回此 set 中所包含元素的逆序视图。 </span><br><span class="line">&gt;E <span class="title function_">first</span><span class="params">()</span> </span><br><span class="line">    返回此 set 中当前第一个（最低）元素。 </span><br><span class="line">&gt;E <span class="title function_">floor</span><span class="params">(E e)</span> </span><br><span class="line">    返回此 set 中小于等于给定元素的最大元素；如果不存在这样的元素，则返回 <span class="literal">null</span>。 </span><br><span class="line">&gt;SortedSet&lt;E&gt; <span class="title function_">headSet</span><span class="params">(E toElement)</span> </span><br><span class="line">    返回此 set 的部分视图，其元素严格小于 toElement。 </span><br><span class="line">&gt;NavigableSet&lt;E&gt; <span class="title function_">headSet</span><span class="params">(E toElement, <span class="type">boolean</span> inclusive)</span> </span><br><span class="line">    返回此 set 的部分视图，其元素小于（或等于，如果 inclusive 为 <span class="literal">true</span>）toElement。 </span><br><span class="line">&gt;E <span class="title function_">higher</span><span class="params">(E e)</span> </span><br><span class="line">    返回此 set 中严格大于给定元素的最小元素；如果不存在这样的元素，则返回 <span class="literal">null</span>。 </span><br><span class="line">&gt;<span class="type">boolean</span> <span class="title function_">isEmpty</span><span class="params">()</span> </span><br><span class="line">    如果此 set 不包含任何元素，则返回 <span class="literal">true</span>。 </span><br><span class="line">&gt;Iterator&lt;E&gt; <span class="title function_">iterator</span><span class="params">()</span> </span><br><span class="line">    返回在此 set 中的元素上按升序进行迭代的迭代器。 </span><br><span class="line">&gt;E <span class="title function_">last</span><span class="params">()</span> </span><br><span class="line">    返回此 set 中当前最后一个（最高）元素。 </span><br><span class="line">&gt;E <span class="title function_">lower</span><span class="params">(E e)</span> </span><br><span class="line">    返回此 set 中严格小于给定元素的最大元素；如果不存在这样的元素，则返回 <span class="literal">null</span>。 </span><br><span class="line">&gt;E <span class="title function_">pollFirst</span><span class="params">()</span> </span><br><span class="line">    获取并移除第一个（最低）元素；如果此 set 为空，则返回 <span class="literal">null</span>。 </span><br><span class="line">&gt;E <span class="title function_">pollLast</span><span class="params">()</span> </span><br><span class="line">    获取并移除最后一个（最高）元素；如果此 set 为空，则返回 <span class="literal">null</span>。 </span><br><span class="line">&gt;<span class="type">boolean</span> <span class="title function_">remove</span><span class="params">(Object o)</span> </span><br><span class="line">    将指定的元素从 set 中移除（如果该元素存在于此 set 中）。 </span><br><span class="line">&gt;<span class="type">int</span> <span class="title function_">size</span><span class="params">()</span> </span><br><span class="line">    返回 set 中的元素数（set 的容量）。 </span><br><span class="line">&gt;NavigableSet&lt;E&gt; <span class="title function_">subSet</span><span class="params">(E fromElement, <span class="type">boolean</span> fromInclusive, E toElement, <span class="type">boolean</span> toInclusive)</span> </span><br><span class="line">    返回此 set 的部分视图，其元素范围从 fromElement 到 toElement。 </span><br><span class="line">&gt;SortedSet&lt;E&gt; <span class="title function_">subSet</span><span class="params">(E fromElement, E toElement)</span> </span><br><span class="line">    返回此 set 的部分视图，其元素从 fromElement（包括）到 toElement（不包括）。 </span><br><span class="line">&gt;SortedSet&lt;E&gt; <span class="title function_">tailSet</span><span class="params">(E fromElement)</span> </span><br><span class="line">    返回此 set 的部分视图，其元素大于等于 fromElement。 </span><br><span class="line">&gt;NavigableSet&lt;E&gt; <span class="title function_">tailSet</span><span class="params">(E fromElement, <span class="type">boolean</span> inclusive)</span> </span><br><span class="line">    返回此 set 的部分视图，其元素大于（或等于，如果 inclusive 为 <span class="literal">true</span>）fromElement。 </span><br></pre></td></tr></table></figure></blockquote>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://guanhuaizhi0708.gitee.io/myblog/2023/05/24/01_%E9%9B%86%E5%90%88%E7%B1%BB/" data-id="cli1ssoyu0000pov67sv38nfy" data-title="" class="article-share-link"><span class="fa fa-share">分享</span></a>
      
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
  
    <a href="/myblog/2023/05/20/hello-world/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">后一篇</strong>
      <div class="article-nav-title">Hello World</div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    

  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/myblog/archives/2023/05/">五月 2023</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/myblog/2023/05/24/01_%E9%9B%86%E5%90%88%E7%B1%BB/">(no title)</a>
          </li>
        
          <li>
            <a href="/myblog/2023/05/20/hello-world/">Hello World</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2023 John Doe<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/myblog/" class="mobile-nav-link">Home</a>
  
    <a href="/myblog/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/myblog/js/jquery-3.6.4.min.js"></script>



  
<script src="/myblog/fancybox/jquery.fancybox.min.js"></script>




<script src="/myblog/js/script.js"></script>





  </div>
</body>
</html>